home *** CD-ROM | disk | FTP | other *** search
- ;-----------------------------------------------------------------------;
- ; STATLINE, by John Socha, Copyright 1986 Ziff-Davis Publishing Co. ;
- ; ;
- ; Here are the two interrupt vectors that we take over. The first ;
- ; interrupt, INT 9, is the hardware interrupt for the keyboard, and ;
- ; it's called every time you push or release a key. ;
- ; ;
- ; The other interrupt, INT 10h, points to the ROM BIOS routines that ;
- ; handle all of the screen I/O. We intercept it so that we can watch ;
- ; for commands to change the display mode. Since STATLINE only works ;
- ; in 80x25 text modes, STATLINE turns itself off as long as the screen ;
- ; is in a different mode. ;
- ;-----------------------------------------------------------------------;
- VECTORS SEGMENT AT 0h
- ORG 9h*4
- KEYBOARD_INT_VECTOR LABEL DWORD ;Keyboard interrupt
- ORG 10h*4
- VIDEO_IO_VECTOR LABEL DWORD ;ROM BIOS Video I/O function calls
- VECTORS ENDS
-
-
- ;-----------------------------------------------------------------------;
- ; STATLINE uses the following flags from the ROM BIOS's data area to ;
- ; control the screen. ;
- ;-----------------------------------------------------------------------;
- ROM_BIOS_DATA SEGMENT AT 40h
- ORG 10h
- EQUIP_FLAG DB ? ;Equipment installed
- ORG 17h
- KBD_FLAG DB ? ;Used to determine display type
- ORG 4Eh
- CRT_START DW ? ;Starting address in buffer
- ORG 63h
- ADDR_6845 DW ? ;3x8 register, where x is B or D
- ROM_BIOS_DATA ENDS
-
-
- ;-----------------------------------------------------------------------;
- ; This section of the ROM in a COMPAQ contains the 6 bytes 'COMPAQ' ;
- ; which we can use to identify a COMPAQ computer. COMPAQ computers ;
- ; have a display adapter that uses the monochrome display, but with ;
- ; registers and memory the same as a color graphics adapter. ;
- ;-----------------------------------------------------------------------;
- COMPAQ_CO EQU 4F43h ;ASCII code of 'CO'
-
- COMPAQ_SEG SEGMENT AT 0F000h
- ORG 0FFEAh
- COMPAQ_ID DW ? ;We should find 'CO' (4F43h) here
- COMPAQ_SEG ENDS
-
-
- ;-----------------------------------------------------------------------;
- ; Here is the STATLINE's entry point. It jumps to the initialization ;
- ; routine which is at the very end so that we can throw it out of ;
- ; memory after we've used it. ;
- ;-----------------------------------------------------------------------;
- CODE_SEG SEGMENT
- ASSUME CS:CODE_SEG, DS:CODE_SEG
- ORG 100h ;Reserve for DOS Program Segment Prefix
- BEGIN: JMP INIT_VECTORS
-
- AUTHOR_STRING DB "Installed Statline, by John Socha"
- DB 0Dh, 0Ah, '$'
-
- OLD_KBD_FLAG DB 0 ;Most recent upper nibble of status
- VIDEO_MODE DB ? ;Current video mode
- STATUS_LINE_ENABLED DB 1 ;0 when we're in graphics modes
-
- ;-----------------------------------------------------------------------;
- ; The following table contains the character/attribute pairs for the ;
- ; states of the Scroll Lock, Num Lock, and Caps Lock keys. ;
- ; ;
- ; The first word contains the address for the character, and the second ;
- ; word contains the character/attribute pair. ;
- ;-----------------------------------------------------------------------;
- ENTRY STRUC
- OFFSET_FROM_TOP DW ? ;Offset from start of display memory
- ATTRIBUTE_CHARACTER DB ? ;Attribute and character code
- ENTRY ENDS
-
- FLAG_CHARACTER_TABLE LABEL WORD
- ENTRY <4084,' '> ;Scroll Lock, ' '
- ENTRY <4084,12h> ;Scroll Lock, double-ended arrow
- ENTRY <4080,' '> ;Num Lock, ' '
- ENTRY <4080,23h> ;Num lock, '#'
- ENTRY <4076,' '> ;Caps Lock, ' '
- ENTRY <4076,18h> ;Caps Lock, up arrow
-
- ROM_KEYBOARD_INT DD ?
- ROM_VIDEO_IO_INT DD ?
-
- ;-----------------------------------------------------------------------;
- ; This procedure sends control off to the ROM BIOS routine, then checks ;
- ; the shift-lock flags on return and writes the new flag characters to ;
- ; the screen. ;
- ;-----------------------------------------------------------------------;
- INTERCEPT_KEYBOARD_INT PROC FAR
- ASSUME CS:CODE_SEG, DS:NOTHING
- PUSHF ;Simulate INT with PUSHF and CALL
- CALL ROM_KEYBOARD_INT ;Let ROM do the work
- CMP STATUS_LINE_ENABLED,1 ;See if Status line enabled.
- JNE NO_STATUS_LINE ;Not enabled.
- CALL CHECK_STATUS_FLAGS ;Check flags and update status line
- NO_STATUS_LINE:
- IRET
- INTERCEPT_KEYBOARD_INT ENDP
-
-
- ;-----------------------------------------------------------------------;
- ; This procedure checks the current setting of KBD_FLAGS against the ;
- ; last setting, and if the flags have changed, it updates the status ;
- ; line display. Check_status_flags also updates Old_kbd_flag. ;
- ;-----------------------------------------------------------------------;
- CHECK_STATUS_FLAGS PROC NEAR
- PUSH AX ;Save all the registers we use
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DI
- PUSH DS
- PUSH ES
- ASSUME CS:CODE_SEG, DS:ROM_BIOS_DATA
- MOV AX,ROM_BIOS_DATA ;Set DS so it points to BIOS data area
- MOV DS,AX
- MOV DX,ADDR_6845 ;Get the base address for the 6845
- MOV AX,0B800h ;Segment address of graphics adapter
- CMP DX,3D0h ;Is this the color graphics adapter?
- JAE IS_COLOR_BOARD ;It's a color board, so don't change AX
- MOV AX,0B000h ;Segment address for monochrome adapter
- IS_COLOR_BOARD:
- MOV ES,AX ;Use extra segment for display memory
-
- ADD DX,03DAh-03D4h ;Point to status register
- MOV BL,KBD_FLAG ;Get flag information
- MOV CL,4 ;Put shift lock flags into lower nibble
- SHR BL,CL
- ASSUME CS:CODE_SEG, DS:CODE_SEG
- MOV AX,CS ;Set DS to the local data (in CS)
- MOV DS,AX
- CMP BL,OLD_KBD_FLAG ;Have any of the status flags changed?
- JE FLAGS_HAVENT_CHANGED ;No, then do nothing
- MOV OLD_KBD_FLAG,BL ;Flags have changed, update status line
- MOV SI,Offset FLAG_CHARACTER_TABLE
-
- MOV CX,3 ;Repeat for three shift lock keys
- SHIFT_LOCK_LOOP:
- PUSH SI
- SHR BL,1 ;Get next flag in carry
- JNC READ_OFFSET ;Flag was 0, SI Ok
- ADD SI,3 ;Skip over information
- READ_OFFSET:
- MOV DI,[SI] ;Get Offset
- MOV AL,[SI+2] ;Get character for this flag
-
- PUSH CX ;Save the CX register
- MOV CL,AL ;Save the character in CL
- WAIT_FOR_NON_RETRACE:
- IN AL,DX ;Read status
- TEST AL,8 ;In vertical retrace?
- JNZ WAIT_FOR_NON_RETRACE ;Wait for vertical retrace to finish
- WAIT_FOR_RETRACE:
- IN AL,DX ;Read status
- TEST AL,8 ;In vertical retrace?
- JZ WAIT_FOR_RETRACE ;No, then wait for vertical retrace
- MOV AL,CL ;Get the character we want to write
- STOSB ;Write character to the screen
- POP CX ;Recover the old value of CX
-
- POP SI
- ADD SI,6 ;Skip to next pair of entries
- LOOP SHIFT_LOCK_LOOP
-
- FLAGS_HAVENT_CHANGED:
- POP ES
- POP DS
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- POP AX
- RET
- CHECK_STATUS_FLAGS ENDP
-
-
- ;-----------------------------------------------------------------------;
- ; This procedure reprograms the 6845 whenever a program switches modes ;
- ; into an 80x25 text mode. ;
- ;-----------------------------------------------------------------------;
- INTERCEPT_VIDEO_IO PROC FAR
- ASSUME CS:CODE_SEG, DS:NOTHING
- OR AH,AH ;Check if called for SET MODE
- JZ SET_MODE ;It's a SET MODE call
- JMP ROM_VIDEO_IO_INT ;Not a SET MODE, call ROM BIOS
- SET_MODE:
- MOV VIDEO_MODE,AL ;Save new video mode
- MOV STATUS_LINE_ENABLED,AH ;Disable STATLINE during mode change
- PUSHF ;Simulate INT with PUSHF, CALL
- CALL ROM_VIDEO_IO_INT ;Let ROM BIOS change video mode
- CALL REPROGRAM_6845 ;Create 26th line again
- MOV OLD_KBD_FLAG,0 ;Flags will be clear in new mode
- CALL CHECK_STATUS_FLAGS ;Make sure we show current flags
- IRET
- INTERCEPT_VIDEO_IO ENDP
-
-
-
- ;-----------------------------------------------------------------------;
- ; The following tables describe how to reprogram the 6845 registers. ;
- ; Each pair describes how to change one register. The first number is ;
- ; the register that we want to reprogram, while the second number is ;
- ; the new value for that register. Reprogram_6845 stops when it sees ;
- ; a 0 for the register number. ;
- ;-----------------------------------------------------------------------;
- MONOCHROME_TABLE LABEL BYTE
- DB 4,26 ;Vertical total, 26 lines
- DB 5,3 ;Vertical total adjust, scan lines
- DB 6,26 ;Vertical displayed, 26 lines
- DB 7,26 ;Vertical sync position, lines
- DB 0 ;End of Monochrome table
-
- COLOR_GRAPHICS_TABLE:
- DB 6,26 ;Vertical displayed
- DB 0 ;End of color graphics adapter table
-
- ;-----------------------------------------------------------------------;
- ; This procedure reprograms the 6845 so that it will show 26 rather ;
- ; than 25 lines. It uses the values from one of the tables above. ;
- ; ;
- ; This procedure also handles the COMPAQ, which is a special case. The ;
- ; COMPAQ uses a monochrome-type display, so it needs to be reprogrammed ;
- ; like a monochrome display, yet writes should be to 3Dxh registers ;
- ; rather than the 3Bxh registers used for an IBM monochrome display. ;
- ; ;
- ; F000:FFEA holds the word 'COMPAQ' on COMPAQ computers, so we can tell ;
- ; when we're running on a COMPAQ. ;
- ;-----------------------------------------------------------------------;
- REPROGRAM_6845 PROC NEAR
- ASSUME CS:CODE_SEG, DS:CODE_SEG
- PUSH AX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DS
- MOV AX,CS
- MOV DS,AX ;Set up Data Seg
- MOV STATUS_LINE_ENABLED,0 ;Initially disable status line
- MOV AL,VIDEO_MODE ;Check video mode
- CMP AL,1 ;In graphics mode?
- JLE GRAPHICS_MODE ;Yes, don't reprogram 6845
- CMP AL,3 ;Is display in a text mode?
- JLE TEXT_MODE ;Yes, then we can reprogram 6845
- CMP AL,7 ;Is it in the monochrome mode?
- JNE GRAPHICS_MODE ;No, then don't reprogram 6845
- TEXT_MODE: ;Yes, reprogram 6845
- MOV STATUS_LINE_ENABLED,1 ;Enable status line in text modes
- MOV SI,Offset MONOCHROME_TABLE
- MOV DX,3B4h ;6845 registers for monochrome display
- PUSH DS
- MOV AX,ROM_BIOS_DATA ;Read equipment flag from low memory
- MOV DS,AX
- ASSUME CS:CODE_SEG, DS:ROM_BIOS_DATA
- MOV AL,EQUIP_FLAG
- AND AL,30h ;Isolate CRT switches
- CMP AL,30h ;Is it the monochrome display?
- POP DS
- JE SET_REGISTERS ;Yes, the registers are correct
- MOV DX,3D4h ;No, set registers for graphics adapter
- PUSH DS
- MOV AX,COMPAQ_SEG ;Now check to see if this is a COMPAQ
- MOV DS,AX
- ASSUME CS:CODE_SEG, DS:COMPAQ_SEG
- CMP COMPAQ_ID, COMPAQ_CO ;Is this the 'CO' from COMPAQ?
- POP DS ;Restore old DS
- ASSUME CS:CODE_SEG, DS:CODE_SEG
- JE SET_REGISTERS ;Is a COMPAQ, use monochrome data
- MOV SI,Offset COLOR_GRAPHICS_TABLE ;No, use color graphics data
-
- SET_REGISTERS:
- CLD ;Clear direction flag for increment
- ADAPTER_LOOP:
- LODSB ;Get register number
- OR AL,AL ;Are we at the end of the table?
- JZ END_OF_ADAPTER_TABLE ;Yes, we're almost done
- OUT DX,AL ;No, select this register
- INC DX ;Point to data register
- LODSB ;Get new register value
- OUT DX,AL ;Set the register to its new value
- DEC DX ;Point back to address register
- JMP ADAPTER_LOOP ;Get the next register/value pair
-
- END_OF_ADAPTER_TABLE:
- GRAPHICS_MODE:
- POP DS
- POP SI
- POP DX
- POP CX
- POP AX
- RET
- REPROGRAM_6845 ENDP
-
-
- ;-----------------------------------------------------------------------;
- ; This procedure initializes the interrupt vectors and the 6845 ;
- ; registers. It initializes both the Monochrome and color graphics ;
- ; adapter address so it will work on the COMPAQ as well as IBM PCs ;
- ;-----------------------------------------------------------------------;
- INIT_VECTORS PROC NEAR
- ASSUME CS:CODE_SEG, DS:CODE_SEG
- LEA DX,AUTHOR_STRING ;Print out the author notice
- MOV AH,9 ;Display this string
- INT 21h
-
- MOV AH,15 ;Check current video mode
- INT 10h ;Call VIDEO_IO ROM BIOS routine
- MOV VIDEO_MODE,AL
- CALL REPROGRAM_6845
- CALL CHECK_STATUS_FLAGS ;Display any flags now on
-
- ASSUME CS:CODE_SEG, DS:VECTORS
- MOV AX,VECTORS ;Set up the data segment for vectors
- MOV DS,AX
- CLI ;Don't allow interrupts
-
- MOV AX,Word Ptr KEYBOARD_INT_VECTOR
- MOV Word Ptr ROM_KEYBOARD_INT,AX
- MOV AX,Word Ptr KEYBOARD_INT_VECTOR[2]
- MOV Word Ptr ROM_KEYBOARD_INT[2],AX
- MOV Word Ptr KEYBOARD_INT_VECTOR, Offset INTERCEPT_KEYBOARD_INT
- MOV Word Ptr KEYBOARD_INT_VECTOR[2],CS
-
- MOV AX,Word Ptr VIDEO_IO_VECTOR
- MOV Word Ptr ROM_VIDEO_IO_INT,AX
- MOV AX,Word Ptr VIDEO_IO_VECTOR[2]
- MOV Word Ptr ROM_VIDEO_IO_INT[2],AX
- MOV Word Ptr VIDEO_IO_VECTOR, Offset INTERCEPT_VIDEO_IO
- MOV Word Ptr VIDEO_IO_VECTOR[2],CS
-
- STI ;Allow interrupts again
- MOV DX,Offset INIT_VECTORS ;End of resident portion
- INT 27h ;Terminate but stay resident
- INIT_VECTORS ENDP
-
-
- CODE_SEG ENDS
-
- END BEGIN